{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">原文地址 [www.cnblogs.com](https://www.cnblogs.com/bliss-/p/12523866.html)\n",
    "\n",
    "---\n",
    "\n",
    "**说明：**\n",
    "\n",
    "modbus 协议一般适用于一个主设备访问多个从设备的硬件开发环境，类似于 zigbee 网络中的一个路由器多个协调器的一对多模型。\n",
    "\n",
    "modbus 常用的寄存器类型为 3X 输入寄存器和 4X 保持寄存器\n",
    "\n",
    "从机 3X 输入寄存器对主机来说是可读不可写状态，从机 4X 保持寄存器对主机来说是可读可写状态\n",
    "\n",
    "---\n",
    "\n",
    "功能码含义\n",
    "\n",
    "04：读取输入寄存器（3x）\n",
    "\n",
    "03：读取保持寄存器（4x）\n",
    "\n",
    "06：写入单个保持寄存器（4x）\n",
    "\n",
    "16：写入多个保持寄存器（4x）\n",
    "\n",
    "---\n",
    "\n",
    "**常用的数据格式：**\n",
    "\n",
    "**主机读取从机输入寄存器数据格式：**\n",
    "\n",
    "\n",
    "```\n",
    "数据实例：03 04 05 61 00 01 61 3A\n",
    "\n",
    "分解：\n",
    "\n",
    "03         04      05          61\n",
    "modbus地址  功能码  寄存器地址高  寄存器地址低                   \n",
    "\n",
    "00          01          61            3A\n",
    "寄存器数量高  寄存器数量低  CRC校验码低位  CRC校验码高位\n",
    "\n",
    "```\n",
    "\n",
    "\n",
    "解释：\n",
    "\n",
    "主机读取 modbus 地址为 03 的从机输入寄存器，从 0x0561（十进制为 1377）地址开始读取一个寄存器。\n",
    "\n",
    "**读取**读取从机输入寄存器**返回数据格式：**\n",
    "\n",
    "```\n",
    "03         04    02   00 02   41   31\n",
    "\n",
    "```\n",
    "\n",
    "```\n",
    "modbus地址 功能码 字节数 数据... CRC低 CRC高\n",
    "\n",
    "```\n",
    "\n",
    "**-------**\n",
    "\n",
    "**主机读取从机保持寄存器数据格式：**\n",
    "\n",
    "```\n",
    "数据实例：03 03 15 1a 00 01 A0 23\n",
    "\n",
    "分解：\n",
    "\n",
    "03          03    15          1A                 \n",
    "modbus地址  功能码  寄存器地址高   寄存器地址低  \n",
    "\n",
    "00          01          A0    23\n",
    "寄存器数量高  寄存器数量低  CRC低 CRC高\n",
    "\n",
    "```\n",
    "\n",
    "解释：\n",
    "\n",
    "　　主机读取 modbus 地址为 03 的从机保持寄存器，从 0x151a（十进制为 5402）地址开始读取一个寄存器。\n",
    "\n",
    "**读取**读取从机保持寄存器**返回数据格式：**\n",
    "\n",
    "```\n",
    "03         03    02   00 02   40   45\n",
    "modbus地址 功能码 字节数 数据... CRC低 CRC高\n",
    "\n",
    "```\n",
    "\n",
    "---\n",
    "\n",
    "**主机写入单个保持寄存器数据格式：**\n",
    "\n",
    "```\n",
    "数据实例：03 06 15 1a 00 32 2C 36\n",
    "\n",
    "分解：\n",
    "\n",
    "03          06    15          1A \n",
    "modbus地址  功能码 寄存器地址高   寄存器地址低                   \n",
    "\n",
    "00       32     2C    36\n",
    "数据高    数据低  CRC低 CRC高\n",
    "\n",
    "```\n",
    "\n",
    "解释：\n",
    "\n",
    "　　主机写入 modbus 地址为 03 从机一个保持寄存器数据，从 0x151a（十进制为 5402）地址开始写入一个寄存器，写入数据为 0x0032。\n",
    "\n",
    "---\n",
    "\n",
    "**写入单个保持寄存器返回数据格式：**\n",
    "\n",
    "如果写入成功，返回数据和写入数据相同\n",
    "\n",
    "**主机写入多个保持寄存器数据格式：**\n",
    "\n",
    "```\n",
    "数据实例：03 10 14 56 00 02 04 00 00 00 50 82 3D\n",
    "\n",
    "分解：\n",
    "\n",
    "03         10     14          56\n",
    "modbus地址  功能码 寄存器地址高   寄存器地址低                      \n",
    "\n",
    "00           02           04      00 00 00 50 \n",
    "寄存器数量高   寄存器数量低   字节数   数据 (从高到低依次)           \n",
    "\n",
    "82     3D\n",
    "CRC低  CRC高\n",
    "\n",
    "```\n",
    "\n",
    "解释：\n",
    "\n",
    "　　主机写入 modbus 地址为 03 从机两个保持寄存器数据，从 0x1456（十进制为 5206）地址开始写入两个寄存器，写入数据为 0x0000、0x0050。\n",
    "\n",
    "**写入多个保持寄存器返回数据格式：**\n",
    "\n",
    "```\n",
    "03         10   14         56 \n",
    "modbus地址 功能码 寄存器地址高 寄存器地址低 \n",
    "\n",
    "00          02         A5    CA\n",
    "寄存器数据高  寄存器数量低 CRC低 CRC高\n",
    "\n",
    "```\n",
    "\n",
    "**常用功能码：**\n",
    "\n",
    "<table border=\"0\" align=\"left\"><tbody><tr><td>数据类型</td><td>功能描述</td><td>功能码</td><td>功能码 (Hex)</td><td>异常功能码 (hex)</td></tr><tr><td>输入寄存器</td><td>读寄存器</td><td>04</td><td>0x04</td><td>0x84</td></tr><tr><td rowspan=\"3\">保持寄存器</td><td>读寄存器&nbsp; &nbsp;&nbsp;</td><td>03</td><td>0x03</td><td>0x83</td></tr><tr><td>写寄存器</td><td>06</td><td>0x06</td><td>0x86</td></tr><tr><td>写寄存器</td><td>16</td><td>0x10</td><td>0x90</td></tr></tbody></table>\n",
    "\n",
    "这个是我自己使用 c 代码模拟的 modbus 数据协议打包格式\n",
    "\n",
    "链接：https://pan.baidu.com/s/1AAflWfiBEh6l6lTAiwwWEQ  \n",
    "提取码：11os\n",
    "\n",
    "常用接口有：  \n",
    "// **读取输入寄存器**  \n",
    "int read_input_registers;  \n",
    "// **读取保持寄存器**  \n",
    "int read_hold_registers;  \n",
    "// **写单个保持寄存器**  \n",
    "int write_hold_register;  \n",
    "// **写多个保持寄存器**  \n",
    "int write_hold_registers;"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
